// Copyright (c) 2022 wick.zt arg-go is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of
// the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

package arg

import (
	"fmt"
	"reflect"
)

type TypeErrorKind int

const (
	NotPointer TypeErrorKind = iota + 1
	NotStruct
	IsNil
	UnknownType
)

type TypeError struct {
	kind TypeErrorKind
	reflect.Type
}

func (err *TypeError) Error() string {
	return fmt.Sprintf("bad type: %d '%s (%s)'", err.kind, err.Type, err.Type.Kind())
}

type TagError struct {
	tag string
}

func (e *TagError) Error() string {
	return fmt.Sprintf("bad tag: '%s'", e.tag)
}

type ValueErrorType int

const (
	PartialToken ValueErrorType = iota + 1
	UnknownToken
	UnknownAttribute
	ValueRequired
	MustNotDefault
	RedefinedArg
	RedefinedAttr
	NullFlag
	InvalidFlag
	UnknownFlag
	UnknownArg
	NoFollowingArg
	InvalidValueRepr
	MissingFollowingArg
)

type ValueError struct {
	typ ValueErrorType
	msg string
	val interface{}
}

func (e *ValueError) Type() ValueErrorType {
	return e.typ
}

func (e *ValueError) Error() string {
	return fmt.Sprintf("bad value: %d, '%v' %s", e.typ, e.val, e.msg)
}

type RuntimeError struct {
	msg string
}

func (e *RuntimeError) Error() string {
	return fmt.Sprintf("runtime error: %s", e.msg)
}
